#include <unistd.h>
#include <strings.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <err.h>


#define WORDS_ACTION	1
#define LINES_ACTION	2
#define BYTES_ACTION	3

#define FILE_BUFFER     2048
extern int wc(int, unsigned long[]);
extern int count (char, unsigned long[], int);

void usage(char* pgname)
{
	fprintf(stdout,"Usage:\n");
	fprintf(stdout,"%s -h\n",pgname);
	fprintf(stdout,"%s -V\n",pgname);
	fprintf(stdout,"%s [options]\n",pgname);

	fprintf(stdout,"Options:\n");
	fprintf(stdout,"%s -V, --version\t\t\tPrint version and quit.\n",pgname);
	fprintf(stdout,"%s -h, --help\t\t\tPrint this information.\n",pgname);

	fprintf(stdout,"%s -w, --words\t\t\tPrint the number of words.\n",pgname);
	fprintf(stdout,"%s -l, --lines\t\t\tPrint the number of lines.\n",pgname);
	fprintf(stdout,"%s -c, --bytes\t\t\tPrint the number of bytes.\n",pgname);

	fprintf(stdout,"Examples:\n");

	fprintf(stdout,"%s foo\n",pgname);
	fprintf(stdout,"%s -l \n",pgname);

}

void imprimir_resultado(int actions[], unsigned long vector_contadores[], char* etiqueta){
	if(actions[0]!=0){
		fprintf(stdout,"%lu\t",vector_contadores[1]);
	}

	if(actions[1]!=0){
		fprintf(stdout,"%lu\t",vector_contadores[0]);
	}

	if(actions[2]!=0){
		fprintf(stdout,"%lu\t",vector_contadores[2]);
	}

	if(etiqueta != NULL){
		fprintf(stdout,"%s", etiqueta);
	}

	fprintf(stdout,"\n");


}

int procesar_entrada(int argc, char *argv[], int optind, int actions[]){
    unsigned long cant_files=(argc-optind);

    unsigned long totales[]={0,0,0};

    unsigned long contadores[]={0,0,0};

    int fdin=0;
    if (cant_files == 0){
    	wc(fdin, contadores);

    	imprimir_resultado(actions, contadores, NULL);

    } else {
    	int i=0;
    	for (i=0; i<cant_files; i++) {
    		fdin = open(argv[i+optind], O_RDONLY, 0);
    		if (fdin == -1) {
			fprintf(stderr, "unable to open %s\n", argv[i+optind]);
			usage(argv[0]);
			exit(1);
		}
    		int respuesta=wc(fdin, contadores);

		if(respuesta!=0){
			fprintf(stderr, "Error reading input: %s\n", argv[i+optind]);
			exit(1);
		}

    		imprimir_resultado(actions, contadores, argv[i+optind]);

    		totales[0]+=contadores[0];
    		totales[1]+=contadores[1];
    		totales[2]+=contadores[2];

        	contadores[0]=0;
        	contadores[1]=0;
        	contadores[2]=0;

    		close(fdin);
    	}

    	imprimir_resultado(actions, totales, "TOTAL");
    }


    return 0;
}

int main(int argc, char *argv[])
{
    int ch;

	static struct option longopts[] = {
             { "version", no_argument, NULL, 'V' },
             { "help", no_argument, NULL, 'h' },
             { "words", no_argument, NULL, 'w' },
             { "lines", no_argument, NULL, 'l' },
             { "bytes", no_argument, NULL, 'c' },
	         { NULL, 0, NULL, 0 }
     };

    int actions[3] = {0};

    while ((ch = getopt_long(argc, argv, "wlcVh", longopts, NULL)) != -1)
	{
         switch (ch) {
         	 case 'l':
				actions[0]=LINES_ACTION;
				break;
			case 'w':
				actions[1]=WORDS_ACTION;
				break;
			case 'c':
				actions[2]=BYTES_ACTION;
				break;
            case 'h':
				usage(argv[0]);
            	exit(0);
      	    	break;
			case 'V':
				printf("-- TP1 --\n");
				printf("Organización de Computadoras - 66.20\n");
				printf("Version 1.0\n");
				exit(0);
      	    	break;
            default:
            	usage(argv[0]);
				exit(0);
				break;
         }

	}

    if (actions[0]==0 && actions[1]==0 && actions[2]==0){
    	actions[0]=LINES_ACTION;
    	actions[1]=WORDS_ACTION;
    	actions[2]=BYTES_ACTION;
    }

    return procesar_entrada(argc, argv, optind, actions);
}
